/**
 * $Revision: 1.0 $
 * $Author: Eric Yang $
 * $Date: Aug 7, 2009 10:38:54 PM $
 *
 * Author: Eric Yang
 * Date  : Aug 7, 2009 10:38:54 PM
 *
 */
package com.gooex.service.base.impl;

import java.util.List;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.c4j.string.StringTools;
import org.c4j.system.web.exception.ServiceException;
import org.c4j.system.web.hibernate.BaseHibernateService;

import com.gooex.domain.base.Product;
import com.gooex.domain.base.Property;
import com.gooex.domain.base.PropertyValue;
import com.gooex.service.base.IPropertyManager;
import com.gooex.service.base.exception.ExceptionCode;
import com.gooex.service.base.exception.PropertyException;

/**
 * @author Eric Yang
 * @version 1.0
 */
public class PropertyManagerImpl extends BaseHibernateService implements IPropertyManager {

	public Property getProperty(String id) {
		if (StringTools.isBlankOrNull(id))
			return null;
		HibernateTemplate template = getHibernateTemplate();
		template.setCacheQueries(true);
		return (Property) template.get(Property.class, id);
	}

	public PropertyValue getPropertyValue(String id) {
		if (StringTools.isBlankOrNull(id))
			return null;
		HibernateTemplate template = getHibernateTemplate();
		template.setCacheQueries(true);
		return (PropertyValue) template.get(PropertyValue.class, id);
	}

	public PropertyValue getPropertyValue(String propertyId, String valueId) {
		HibernateTemplate template = getHibernateTemplate();
		template.setCacheQueries(true);
		String sql = "FROM " + PropertyValue.class.getName() + " WHERE property.id = ? AND id=? ";
		List<PropertyValue> propertyValues = template.find(sql, new Object[] { propertyId, valueId });
		if (propertyValues == null || propertyValues.size() == 0)
			return null;
		return propertyValues.get(0);
	}

	public List<Property> getProperties() {
		HibernateTemplate template = getHibernateTemplate();
		template.setCacheQueries(true);
		return template.find("from Property");
	}

	public Property getPropertyByName(String name) {
		HibernateTemplate template = getHibernateTemplate();
		template.setCacheQueries(true);
		String hql = "from " + Property.class.getName() + " where name=?";
		List<Property> propertys = template.find(hql, name);
		if (propertys != null && propertys.size() == 1)
			return propertys.get(0);
		return null;
	}

	public void saveProperty(Property property) {
		HibernateTemplate template = getHibernateTemplate();
		if (StringTools.isBlankOrNull(property.getId())) {
			property.setId(null);
			template.save(property);
		} else {
			getSessionFactory().evict(Property.class, property.getId());
			template.saveOrUpdate(property);
		}
		String roleName = Property.class.getName() + ".values";
		getSessionFactory().evictCollection(roleName);
		getSessionFactory().evict(Property.class, property.getId());
		String productId = property.getProduct().getId();
		getSessionFactory().evictCollection(Product.class.getName() + ".properties", productId);
		getSessionFactory().evict(Product.class, productId);
	}

	public void removeAllValues(Property property) {
		Query query = getSession().createQuery("delete from " + PropertyValue.class.getName() + " where property.id=?");
		query.setParameter(0, property.getId());
		query.executeUpdate();
		getHibernateTemplate().flush();
	}

	public void removeProperty(Property property) throws PropertyException {
		property = getProperty(property.getId());
		removeAllValues(property);
		getSession().createQuery("delete from " + Property.class.getName() + " where id=?").setParameter(0,
				property.getId()).executeUpdate();
		// getHibernateTemplate().delete(property);
	}

	public List<PropertyValue> getPropertyValues(String propertyID) {
		Property property = getProperty(propertyID);
		if (property != null)
			return property.getValues();
		return null;
	}

	public void removePropertyValue(PropertyValue propertyValue) throws PropertyException {
		propertyValue = getPropertyValue(propertyValue.getId());
		Property property = propertyValue.getProperty();
		property.getValues().remove(propertyValue);
		propertyValue.setProperty(null);
		getHibernateTemplate().delete(propertyValue);
		saveProperty(property);
	}

	public void savePropertyValue(PropertyValue propertyValue) {
		getHibernateTemplate().save(propertyValue);
	}

	public void assertPropertiesExists(List<PropertyValue> propertyValues) {
		for (PropertyValue item : propertyValues) {
			assertPropertyExists(item);
		}
	}

	/**
	 * 参数值是否存在
	 */
	public void assertPropertyExists(PropertyValue item) {
		if (getPropertyValue(item.getId()) == null) {
			throw new ServiceException(ExceptionCode.PROPERTY_VALUE_NOT_EXISTS, new Object[] { item.getId() },
					"property value not exists");
		}
	}

	public Property saveOrUpdateProperty(Property property, List<String> values) {
		Property updateProperty = getProperty(property.getId());
		if (updateProperty == null)
			updateProperty = property;
		if (values != null && values.size() > 0) {
			removeAllValues(property);
			updateProperty.getValues().clear();
			for (int i = 0; i < values.size(); i++) {
				PropertyValue value = new PropertyValue();
				value.setValue(values.get(i));
				updateProperty.addValue(value);
			}
		}
		updateProperty.lightCopy(property);
		saveProperty(updateProperty);
		return updateProperty;
	}

}
